package org.lex.progress;

import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;

public class DefaultProgress implements Progress {
	private long minimum = 0L;
	private long progress = 0L;
	private long maximum = 100L;
	private long startTime = 0L;
	// ===============================
	protected Status state = Status.NEW;
	protected int threshold = 8192;
	// ===============================
	private EventListenerList listenerList = null;

	public DefaultProgress() {
		this(0, 100);
	}

	public DefaultProgress(long min, long max) {
		this(min, max, min);
	}

	public DefaultProgress(long min, long max, long progress) {
		this.minimum = min;
		this.maximum = max;
		this.progress = progress;
		this.state = Status.NEW;
		this.setStartTime(System.currentTimeMillis());
		this.listenerList = new EventListenerList();
	}

	public long getMinimum() {
		return this.minimum;
	}

	protected void setMinimum(long min) {
		this.minimum = min;
	}

	public long getProgress() {
		return progress;
	}

	protected void setProgress(long progress) {
		this.progress = progress;
	}

	public long getMaximum() {
		return maximum;
	}

	protected void setMaximum(long max) {
		this.maximum = max;
	}

	protected void setStartTime(long timeMillis) {
		this.startTime = timeMillis;
	}

	public long elapsedTime() {
		return System.currentTimeMillis() - startTime;
	}

	public void addProgressListener(ProgressListener l) {
		this.listenerList.add(ProgressListener.class, l);
	}

	public void removeProgressListener(ProgressListener l) {
		this.listenerList.remove(ProgressListener.class, l);
	}

	public Status getStatus() {
		return state;
	}

	protected void fireProgressStart() {
		this.state = Status.RUNNING;
		ProgressEvent e = null;
		Object[] listeners = listenerList.getListenerList();
		for (int i = listeners.length - 2; i >= 0; i -= 2) {
			if (listeners[i] == ChangeListener.class) {
				if (null == e)
					e = new ProgressEvent(this);
				((ProgressListener) listeners[i + 1]).progressStart(e);
			}
		}
	}

	protected void fireProgressUpdate() {
		this.state = Status.RUNNING;
		ProgressEvent e = null;
		Object[] listeners = listenerList.getListenerList();
		for (int i = listeners.length - 2; i >= 0; i -= 2) {
			if (listeners[i] == ChangeListener.class) {
				if (null == e)
					e = new ProgressEvent(this);
				((ProgressListener) listeners[i + 1]).progressUpdate(e);
			}
		}
	}

	protected void fireProgressFinish() {
		this.state = Status.RUNNING;
		ProgressEvent e = null;
		Object[] listeners = listenerList.getListenerList();
		for (int i = listeners.length - 2; i >= 0; i -= 2) {
			if (listeners[i] == ChangeListener.class) {
				if (null == e)
					e = new ProgressEvent(this);
				((ProgressListener) listeners[i + 1]).progressFinish(e);
			}
		}
	}

	public String toString() {
		StringBuilder b = new StringBuilder();
		b.append(getClass().getName());
		b.append("[state=").append(state);
		b.append(", minimum=").append(minimum);
		b.append(", progress=").append(progress);
		b.append(", maximum=").append(maximum);
		b.append(", elapsed=").append(elapsedTime());
		b.append(']');
		return b.toString();
	}
}
